package com.ophiux.wechat.executor;

import java.util.SortedMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ophiux.wechat.model.CM_ReFundRequest;
import com.ophiux.wechat.model.ReFundResponse;
import com.ophiux.wechat.model.Refund;
import com.ophiux.wechat.utils.CommonUtil;
import com.ophiux.wechat.utils.MapBuilder;
import com.ophiux.wechat.utils.ResponseDealUtil;
import com.ophiux.wechat.utils.WeChatSignUtil;
import com.ophiux.wechat.utils.XmlUtil;

/**
 * 微信普通商户模式退费业务执行器
 * @author chenh
 * 2016-11-15
 *
 */
public class WXReFundExecutor implements Executor{

 	private static Logger logger = LoggerFactory.getLogger(WXReFundExecutor.class);
	
	/**
	 * 微信公众号支付---退款URL地址
	 */
	private static String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
	
	/**
	 * HTTPS调用退款接口操作异常
	 */
	private static String HTTPS_ERROR_MSG = "HTPS方式调用--退款操作异常";
	private static String HTTPS_ERROR = "0";
	
	/**
	 * 微信退款接口结果判断标识
	 */
	private static String RETURN_SUCCESS = "SUCCESS";
	private static String RETURN_FAIL = "FAIL";
	/**
	 * 业务结果标识
	 */
	private static String RESULT_SUCCESS = "SUCCESS";
	private static String RESULT_FAIL = "FAIL";
	
	/**
	 * 普通商户退费请求参数
	 */
	private CM_ReFundRequest cm_refund_request;
	
	/**
	 * 商户平台-API安全秘钥，用于构造签名
	 */
	private String api_key;
	/**
	 * 微信退款证书安装地址
	 */
	private String sslFilePath;
	 
	
	public WXReFundExecutor(CM_ReFundRequest _cm_refund_request,
			String _api_key,String sslFilePath ){
		this.cm_refund_request = _cm_refund_request;
		this.api_key = _api_key;
		this.sslFilePath = sslFilePath;
	}
	
	@Override
	public String execute() {
		// TODO Auto-generated method stub
		// 商户号
		String mch_id = cm_refund_request.getMch_id();
				// 随机字符串
		String nonce_str = CommonUtil.getNonceStr();
				// 商户订单号
		String out_trade_no =cm_refund_request.getOut_trade_no();
				
		//操作员帐号, 默认为商户号 
		String op_user_id= mch_id;  //陈辉
		//商户系统内部的退款单号，商户系统内部唯一，同一退款单号多次请求只退一笔 
		String out_refund_no=cm_refund_request.getOut_refund_no();
		//退款金额 
		String refund_fee=cm_refund_request.getRefund_fee();
		//总金额 
		String total_fee=cm_refund_request.getTotal_fee();
		//APPID
		String appid = cm_refund_request.getAppid();
		//商户后台支付api安全秘钥
		String api_key = this.api_key;
		
		/**
		 * 组装SortedMap
		 */
		String[] keys = new String[]{"appid","mch_id","nonce_str","op_user_id",
				"out_refund_no","refund_fee","total_fee","out_trade_no"
				}; 
		String[] values = new String []{appid,mch_id,nonce_str,op_user_id,
				out_refund_no,refund_fee,total_fee,out_trade_no};
		/**
		 * 生成SortMap,用作签名
		 */
		SortedMap<String, String> packageParams = 
				MapBuilder.getInstance().buildSortMap(keys, values);
	
		//生成微信方需要的签名
		String sign = WeChatSignUtil.getInstance(api_key).createSign(packageParams);
		/**
		 * 拼接微信公众号支付退款参数
		 * 普通商户退款参数
		 */
		String refund_xmlParam = "<xml>" + 
				     "<appid>" + appid + "</appid>" + 
				     "<mch_id>"+ mch_id + "</mch_id>" + 
					"<nonce_str>" + nonce_str+ "</nonce_str>" + 
					"<op_user_id>" + op_user_id+ "</op_user_id>" +
					"<out_refund_no>" + out_refund_no+ "</out_refund_no>" +
					"<out_trade_no>" + out_trade_no+ "</out_trade_no>" +
					"<refund_fee >" + refund_fee + "</refund_fee >" +
					"<total_fee >" + total_fee + "</total_fee >" +
				       "<sign>" + sign + "</sign>"+ 
				       "</xml>";
		
		logger.info("普通商户调用微信退款请求参数:"+refund_xmlParam);
		
		Refund reFund=new Refund();
		String result = "";
	//	reFund = new GetWxOrderno().getWxRefund(REFUND_URL, refund_xmlParam);
		/**
		 * 调用https安全请求---退款
		 */
		try {
			 result = CommonUtil
					.getPostMethodSSL(REFUND_URL, refund_xmlParam, sslFilePath, mch_id);
			 logger.info("微信普通商户-退款执行返回结果："+result);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			logger.info("HTPS方式调用--退款操作异常"+"退款参数:"+refund_xmlParam);
			return ResponseDealUtil.toRefundErrorMessage(HTTPS_ERROR, HTTPS_ERROR_MSG);
		}
		/**
		 * 解析返回结果
		 */
		reFund = analysisRefundResult(result);
		
		String reFundMessage="";
		//
		ReFundResponse message=new ReFundResponse();
		try {
			if(reFund.getReturn_code().equals(RETURN_SUCCESS)){
				/**
				 * 接口请求通过
				 */
				if(reFund.getResult_code().equals(RESULT_SUCCESS)){
					//退款操作成功
					reFundMessage = ResponseDealUtil.toRefundSuccessMessage(reFund);
				}else{
					//退款操作失败
					reFundMessage = ResponseDealUtil
							.toRefundErrorMessage(reFund.getErr_code(), reFund.getErr_code_des());
				}
				 
			}else{
				/**
				 * 接口请求不通过
				 */
				reFundMessage = ResponseDealUtil  
						.toRefundErrorMessage("0", reFund.getReturn_msg());
			}
					
		} catch (Exception e) {
				e.printStackTrace();
			reFundMessage = ResponseDealUtil  
						.toRefundErrorMessage("0", "程序中途处理异常");
		} 
		
		logger.info("微信普通商户-退款-返回给调用方的参数："+reFundMessage);
		
		return reFundMessage;
		
	}
	
	
	/**
	 * 退款接口微信响应参数解析
	 * @author chenh
	 * @param  响应结果   xml格式
	 * 2016-11-16
	 * 实例：
	 * <xml>
	   <return_code><![CDATA[SUCCESS]]></return_code>
	   <return_msg><![CDATA[OK]]></return_msg>
	   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
	   <mch_id><![CDATA[10000100]]></mch_id>
	   <nonce_str><![CDATA[NfsMFbUFpdbEhPXP]]></nonce_str>
	   <sign><![CDATA[B7274EB9F8925EB93100DD2085FA56C0]]></sign>
	   <result_code><![CDATA[SUCCESS]]></result_code>
	   <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>
	   <out_trade_no><![CDATA[1415757673]]></out_trade_no>
	   <out_refund_no><![CDATA[1415701182]]></out_refund_no>
	   <refund_id><![CDATA[2008450740201411110000174436]]></refund_id>
	   <refund_channel><![CDATA[]]></refund_channel>
	   <refund_fee>1</refund_fee> 
	</xml>
	 */
	public Refund analysisRefundResult(String response){
		  String return_code="";
		  String err_code_des="";
		  String result_code="";
		  Refund reFund=new Refund();
	      try{
		     System.out.println(response);
		     System.out.println("-----------------------------------");
		     XmlUtil xm=new XmlUtil();
		     return_code=xm.getValue(response, "return_code");
		     String return_msg=xm.getValue(response,"return_msg");
		     
	    	 reFund.setReturn_msg(return_msg);
		     reFund.setReturn_code(return_code);
		     if(return_code.equals(RESULT_FAIL)){
		    	 /**
		    	  * 操作失败
		    	  */
		    	 logger.info("错误原因!"+return_msg);
		     }else{
		    	 /**
		    	  * 操作成功
		    	  * result_code=SUCCESS 退款成功
		    	  */
		    	 result_code=xm.getValue(response, "result_code");
		    	 reFund.setResult_code(result_code);
		    	 if(result_code.equals(RESULT_FAIL)){
		    		 /**
		    		  * 退款业务失败
		    		  * err_code/err_code_des有返回
		    		  */
		    		 String err_code=xm.getValue(response, "err_code");
		    		 err_code_des=xm.getValue(response,"err_code_des");
		    		 
		    		 reFund.setErr_code(err_code);
			    	 reFund.setErr_code_des(err_code_des);
		    	 } 
		    	
	    		 String appid=xm.getValue(response, "appid");
	    		 reFund.setAppid(appid);
	    		 String mch_id=xm.getValue(response, "mch_id");
	    		 reFund.setMch_id(mch_id);
	    		
	    		 String nonce_str=xm.getValue(response, "nonce_str");
	    		 reFund.setNonce_str(nonce_str);
	    		 String sign=xm.getValue(response, "sign");
	    		 reFund.setSign(sign);
	    		 String transaction_id=xm.getValue(response, "transaction_id");
	    		 reFund.setTransaction_id(transaction_id);
	    		 String out_trade_no=xm.getValue(response, "out_trade_no");
	    		 reFund.setOut_trade_no(out_trade_no);
	    		 String out_refund_no=xm.getValue(response, "out_refund_no");
	    		 reFund.setOut_refund_no(out_refund_no);
	    		 String refund_id=xm.getValue(response, "refund_id");
	    		 reFund.setRefund_id(refund_id);
	    		 String refund_channel=xm.getValue(response, "refund_channel");
	    		 reFund.setRefund_channel(refund_channel);
	    		 String refund_fee=xm.getValue(response, "refund_fee");
	    		 reFund.setRefund_fee(refund_fee);
	    		 String coupon_refund_fee=xm.getValue(response, "coupon_refund_fee");
	    		 reFund.setCoupon_refund_fee(coupon_refund_fee);
	    		 String total_fee=xm.getValue(response, "total_fee");
	    		 reFund.setTotal_fee(total_fee);
	    		 String cash_fee=xm.getValue(response, "cash_fee");
	    		 reFund.setCash_fee(cash_fee);
	    		 String coupon_refund_count=xm.getValue(response, "coupon_refund_count");
	    		 reFund.setCoupon_refund_count(coupon_refund_count);
	    		 String cash_refund_fee=xm.getValue(response, "cash_refund_fee");
	    		 reFund.setCash_refund_fee(cash_refund_fee);
		    	 
		     }
		     System.out.println("return_code="+return_code);
		     System.out.println("result_code="+result_code);
		     System.out.println("err_code_des="+err_code_des);
		     System.out.println("-----------------------------------");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return reFund;
	}
	
public static void main(String[] args) {
	String result = "";
	//	reFund = new GetWxOrderno().getWxRefund(REFUND_URL, refund_xmlParam);
		/**
		 * 调用https安全请求---退款
		 */
		try {
			String refund_xmlParam = "<xml><appid>wxb27c8659a73b6ad4</appid><mch_id>1458046902</mch_id><nonce_str>1722007408</nonce_str><op_user_id>1458046902</op_user_id><out_refund_no>12201801251707000128912</out_refund_no><out_trade_no>9201801251705053976211</out_trade_no><refund_fee >1500</refund_fee ><total_fee >1500</total_fee ><sign>513A908501E23FC9C3646A0FBA76E67A</sign></xml>";
			result = CommonUtil
					.getPostMethodSSL(REFUND_URL, refund_xmlParam, "D:\\cer\\wuYuan\\apiclient_cert.p12", "1458046902");
			 logger.info("微信普通商户-退款执行返回结果："+result);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
}
}
